package com.taobaolite.cart_has_items;

import com.taobaolite.item.Item;
import com.taobaolite.item.ItemBody;
import com.taobaolite.item.ItemRepository;
import com.taobaolite.user.guest.Guest;
import com.taobaolite.user.guest.GuestRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import javax.transaction.Transactional;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Service
public class CartService {
    private final CartRepository cartRepo;
    private final ItemRepository itemRepo;
    private final GuestRepository guestRepo;

    @Autowired
    public CartService(CartRepository cartRepo, ItemRepository itemRepo, GuestRepository guestRepo) {
        this.cartRepo = cartRepo;
        this.itemRepo = itemRepo;
        this.guestRepo = guestRepo;
    }

    public List<CartBody> getCart(Long userId) {
        List<CartHasItems> cartHasItemsList = cartRepo.findByUserId(userId);
        List<CartBody> cartBodyList = new ArrayList<>();

        for (CartHasItems c : cartHasItemsList) {
            CartBody cartBody = new CartBody(
                    new ItemBody(c.getCartId().getItem()),
                    c.getCartId().getGuest().getGuestId(),
                    c.getAmount(),
                    c.getTime()
            );
            cartBodyList.add(cartBody);
        }

        return cartBodyList;
    }

    @Transactional
    public PutCart putCart(Long userId, Long itemId, Integer amount) {
        CartHasItems cartHasItems = cartRepo.findByUserIdAndItemId(userId, itemId)
                .orElseThrow(() -> new ResponseStatusException(
                        HttpStatus.NOT_FOUND,
                        "User " + userId + " does not have item " +
                                itemId +" in cart."
                ));

        cartHasItems.setAmount(amount);

        return new PutCart(userId, itemId, amount);
    }

    @Transactional
    public CartBody updateCart(Long userId, PutCart putCart) {
        Item item = itemRepo.findById(putCart.getItemId())
                .orElseThrow(() -> new ResponseStatusException(
                        HttpStatus.NOT_FOUND,
                        "Item with ID " +
                                putCart.getItemId() +
                                " does not exist."
                ));

        Guest guest = guestRepo.findById(userId)
                .orElseThrow(() -> new ResponseStatusException(
                        HttpStatus.NOT_FOUND,
                        "Guest with ID " + userId + " deos not exist."
                ));

        CartHasItems cartHasItems = new CartHasItems(
                item,
                guest,
                putCart.getAmount(),
                new Timestamp(System.currentTimeMillis())
        );

        cartRepo.save(cartHasItems);

        return new CartBody(
                new ItemBody(item),
                userId,
                cartHasItems.getAmount(),
                cartHasItems.getTime()
        );
    }

    @Transactional
    public void deleteItemInCart(Long userId, Long itemId) {
        CartHasItems cartHasItems = cartRepo.findByUserIdAndItemId(userId, itemId)
                .orElseThrow(() -> new ResponseStatusException(
                        HttpStatus.NOT_FOUND,
                        "User " + userId + " does not have item " +
                                itemId +" in cart."
                ));
        cartRepo.deleteById(cartHasItems.getCartId());
    }
}
